package de.hmm.hwip.connection.client;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;

import android.util.Log;

import de.hmm.hwip.connection.api.IConIn;

/**
 * OSGi Spot network service
 * Listen on Socket, wait for connection
 * 
 * @author johannes mendel
 * @version 24.10.2012
 *
 */
public class SpotServer implements Runnable {
	
	/**
	 * Class identifier to debug
	 */
	final private static String TAG = "Spot Server (connection client)";
	
	/**
	 * network osgi service Interface
	 */
	private IConIn service = null;
	
	/**
	 * Spot server socket - is listening for connection
	 */
	private static ServerSocket spotserver;
	
	/**
	 * Spot port where connection can enter the system
	 */
	private static int spotPort = 7601;
	
	/**
	 * used socket
	 */
	private Socket client;

	/**
	 * OSGi bundlecontext
	 */
	private BundleContext context;
	
	/**
	 * service Tracker to the network service
	 */
	private ServiceTracker serviceTracker;
	
	/**
	 * identifier if Server is open or closed
	 */
	private static boolean open = true;
	
	/**
	 * Class Constructor
	 * @param service -> OSGi Connection Service
	 * @param context -> OSGi bundle context
	 */
	public SpotServer(BundleContext context){
		this.context = context;
	}
	
	@Override
	public void run() {
		serviceTracker = new ServiceTracker(context, IConIn.class.getName(), null );
		serviceTracker.open();
    	
		//guiservice = new GuiCommandReceiver();
		/*
        Hashtable<String, Object> params = new Hashtable<String, Object>();
        params.put( org.osgi.framework.Constants.SERVICE_PID, IRequest.class.getName());
        params.put( org.osgi.framework.Constants.SERVICE_DESCRIPTION,"Provides Gui Service");
        context.registerService(IRequest.class.getName(), guiservice, params);
    	*/
        
    	synchronized (this) {
    		while(true)
    		{
    		 	service = (IConIn) serviceTracker.getService();
	    		if (service != null)
	    		{
	    			openSocket();
	    			break;
	    		}else{
	    			Log.w(TAG, "InCon service is not available");
	    			try {
						wait(5000);
					} catch (InterruptedException e) {
						Log.e(TAG, "wait exception (InCon service");
					}
	    		}
    		}
    	}
		
	}
	
	private void openSocket(){
		try
		{
			// generate new server socket
			spotserver = new ServerSocket(spotPort);
			
			while(open) 
			{
				Log.i(TAG, "Listen on port: " + spotPort + "...");
				// accept the connect ...
				client = spotserver.accept();
				
				// ... and start the network service thread
				service.startCon(client, context);
			}
			
			client.close();
			spotserver.close();
		}
	    catch(Exception e) 
	    {
	    	Log.e(TAG, "Exception: " + e.getMessage());
	    }
	}
	
	/** closes socket **/
	private static void closeSocket()
	{
		try {
			spotserver.close();
		} catch (IOException e) {
			Log.e(TAG, "unable to close Gateway socket");
		}
	}
	
	/**
	 * Method to close the Server
	 */
	public static void closeSpot(){
		open = false;
	}

}
